import {
  forwardRef,
  useCallback,
  useEffect,
  useImperativeHandle,
  useMemo,
  useRef,
  useState,
} from 'react';
import EditableTable from '../EditableTable';
import { DataType } from './ServerModal';
import { Radio, Tooltip } from 'antd';
import { InbizIcon, uuid } from '@inbiz/utils';
import { getMessage, TextWidget } from '@inbiz/react';
import { toCase } from './utils';

type IOutputTableProps = {
  modalTitle?: string;
  selectDatas?: DataType[];
  resultKeys?: string[];
  isPrimaryKey?: boolean;
};

type reacdType = {
  Name: string;
  Path: string;
  IsSingle: boolean;
  SuccessMark: string;
  id: string;
  children?: reacdType[];
  key: string;
};

type IKey = {
  type: 0 | 1 | 2 | 3 | 4 | 5; // 4 标识对象， 5 标识数组
  name: string;
  children: IKey[];
};
const getKeys = (
  data: IKey | IKey[],
  parentKey: string = '', // 父级key
  isArray: boolean = true, // 是否处理数组中内部数据
  linksymbol: string = '.',
  list: string[] = [],
) => {
  if (data) {
    if (Array.isArray(data)) {
      data.forEach((item) => {
        getKeys(item, parentKey, isArray, linksymbol, list);
      });
    } else {
      const itemKey = parentKey
        ? parentKey + linksymbol + data.name
        : data.name;
      list.push(itemKey);
      if (data?.children && isArray) {
        if (data.type == 5) {
          if (data.children[0].type == 4) {
            getKeys(
              data.children[0].children,
              itemKey,
              false,
              linksymbol,
              list,
            );
          }
        } else {
          getKeys(data.children, itemKey, isArray, linksymbol, list);
        }
      }
    }
  }
  return list;
};
const getObjectKeys = (
  data: IKey | IKey[],
  parentKey: string = '', // 父级key
  isArray: boolean = true, // 是否处理数组中内部数据
  linksymbol: string = '.',
) => {
  const list: string[] = [];
  if (parentKey) {
    list.push(parentKey);
  }
  if (data) {
    getKeys(
      Array.isArray(data) ? data[0].children : data,
      parentKey,
      isArray,
      linksymbol,
      list,
    );
  }
  return list;
};

const OutputTable = (props: IOutputTableProps, ref: any) => {
  const { selectDatas, modalTitle, resultKeys } = props;

  const [outDataSource, setOutDataSource] = useState<reacdType[]>([]);
  const [selectDataSource, setSelectDataSource] = useState<reacdType[]>([]);

  useImperativeHandle(
    ref,
    () => {
      return { outDataSource, setOutDataSource };
    },
    [outDataSource],
  );

  useEffect(() => {
    if (selectDatas?.length) {
      let response = selectDatas?.[0]?.OutParm;
      let dataSource: reacdType[] = [];
      if (response) {
        toCase(response)
        let pathArr = getObjectKeys(response, '$');
        if (!outDataSource.length && resultKeys) {
          setOutDataSource(
            resultKeys.map((item) => {
              return {
                Path: '',
                IsSingle: false,
                SuccessMark: '',
                Name: item,
                id: uuid(8, 23),
                key: uuid(8, 23),
              };
            }),
          );
        }
        pathArr.forEach((item: string) => {
          if (
            item.split('.')[1] === 'success' &&
            item.split('.').length === 2
          ) {
            setOutDataSource((value) => {
              let oldv = [...value];
              let num = oldv.findIndex((v) => v.Name === 'success');
              if (num > -1) {
                oldv[num].Path = item;
              }
              return oldv;
            });
          }

          if (item.split('.')[1] === 'total' && item.split('.').length === 2) {
            setOutDataSource((value) => {
              let oldv = [...value];
              let num = oldv.findIndex((v) => v.Name === 'total');
              if (num > -1) {
                oldv[num].Path = item;
              }
              return oldv;
            });
          }

          if (item.split('.')[1] === 'rows' && item.split('.').length === 2) {
            setOutDataSource((value) => {
              let oldv = [...value];
              let num = oldv.findIndex((v) => v.Name === 'rows');
              if (num > -1) {
                oldv[num].Path = item;
              }
              return oldv;
            });
          }
          dataSource.push({
            Path: item,
            IsSingle: false,
            SuccessMark: '',
            Name: item.split('.')[item.split('.').length - 1],
            id: uuid(8, 23),
            key: uuid(8, 23),
          });
        });
        setSelectDataSource(dataSource);
        if (!outDataSource[1]?.children) {
          setOutDataSource((outData) => {
            let oldData = [...outData];
            let num = oldData.findIndex((item) => item.Name === 'rows');
            if (num > -1) {
              if (oldData[num].Path) {
                let path = oldData[num].Path;
                let subValue = dataSource
                  .filter((item) => item.Path.includes(`${path}.`))
                  .filter(
                    (item) =>
                      item.Path.split('.').length ===
                      path.split('.').length + 1,
                  );
                oldData[num].children = subValue.length
                  ? [...subValue]
                  : undefined;
              }
            }
            return oldData;
          });
        }
      }
    }
  }, [selectDatas]);

  const editRef = useRef<{ upData: (data: any[]) => void }>(null);
  const hanleChange = useCallback((value, record) => {
    //@ts-ignore
    let res: reacdType[] = editRef.current?.getDataSource();
    const index = res.findIndex((item) => !!item.children);
    let newRes = res[index]?.children?.map((item) => {
      return {
        ...item,
        IsSingle: false,
      };
    });

    let num = newRes!.findIndex((item) => item.key === record.key);
    if (num > -1) {
      newRes![num].IsSingle = true;
    }
    res[index].children = [...newRes!];
    editRef.current?.upData([...res]);
  }, []);

  const rowClassName = (record: reacdType, index: number) => {
    if (record.Name === 'success') {
      return 'outputRadiodisabled outsuccess';
    }

    if (record.Path?.split('.').length > 2) {
      if (
        record.Name === 'success' ||
        record.Name === 'rows' ||
        record.Name === 'total'
      ) {
        return 'outputdisabled outputRadiodisabled';
      }

      return 'outputdisabled';
    }

    return 'outputdisabled outputRadiodisabled';
  };
  const columns = useMemo(() => {
    return [
      {
        dataIndex: 'Name',
        title: getMessage('ApiQuery.parameterName'),
        key: 'Name',
        width: 260,
        editData: {
          beforEdit: () => {
            return false;
          },
        },
        render: (value: boolean, record: reacdType) => {
          return value;
        },
      },
      {
        dataIndex: 'Path',
        title: getMessage('ApiQuery.address'),
        key: 'Path',
        width: modalTitle === 'delete' ? 511 : 415,
        editData: {
          type: 'Select',
          options: selectDataSource?.map((item) => {
            return {
              label: item.Path,
              value: item.Path,
            };
          }),
          onChange: (value: string, record: reacdType, dataIndex: string) => {
            if (record.Name === 'rows' || record.Name === 'Rows') {
              setOutDataSource((v) => {
                let oldv = [...v];
                const index = oldv.findIndex(
                  (item) => item.Name === record.Name,
                );
                let subData = selectDataSource
                  .filter((item) => item.Path.includes(`${value}.`))
                  .filter(
                    (item) =>
                      item.Path.split('.').length ===
                      value.split('.').length + 1,
                  );

                if (subData.length) {
                  oldv[index].children = [...subData];
                } else {
                  oldv[index].children = undefined;
                }
                return oldv;
              });
            }
            setOutDataSource((source) => {
              let oldSource = [...source];
              let num = oldSource.findIndex((item) => item.key === record.key);

              if (num > -1) {
                oldSource[num].Path = value;
              }

              return oldSource;
            });
          },
        },
      },
      props.isPrimaryKey
        ? {
            dataIndex: 'IsSingle',
            title: getMessage('ApiQuery.uniqueIdentification'),
            key: 'IsSingle',
            width: 96,
            render: (value: boolean, record: reacdType) => {
              if (
                record.Name !== 'success' &&
                record.Name !== 'rows' &&
                record.Name !== 'total'
              ) {
                return (
                  <Radio
                    checked={value}
                    onChange={(value) => {
                      hanleChange(value, record);
                    }}
                  />
                );
              }
              return '';
            },
          }
        : undefined,
      {
        dataIndex: 'SuccessMark',
        title: (
          <span>
            <TextWidget>ApiQuery.successFlag</TextWidget>
            <Tooltip
              title={getMessage('ApiQuery.successTitle')}
              className="SuccessMarkIcon"
            >
              <InbizIcon
                type="icon-ic-89"
                style={{ marginLeft: 4, cursor: 'pointer' }}
              />
            </Tooltip>
          </span>
        ),
        key: 'SuccessMark',
        width: 180,
        editData: {
          beforEdit: (record: reacdType, index: number) => {
            if (record.Name !== 'success') {
              return false;
            }
            return true;
          },
          type: 'Input',
        },
      },
    ].filter((item) => !!item);
  }, [hanleChange, props.isPrimaryKey, selectDataSource]);
  return (
    <div className="outputTable">
      <EditableTable
        disableDraggable={true}
        ref={editRef}
        //@ts-ignore
        columns={
          modalTitle === 'delete'
            ? columns.filter((item) => item.dataIndex !== 'IsSingle')
            : columns
        }
        addBtn={false}
        deleteBtn={false}
        isRowSelection={false}
        dataSource={outDataSource}
        //@ts-ignore
        rowClassName={rowClassName}
      />
    </div>
  );
};

export default forwardRef(OutputTable);


